package com.ruoyi.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.xbatis.core.mybatis.mapper.context.Pager;
import cn.xbatis.core.sql.executor.Where;
import cn.xbatis.core.sql.executor.chain.QueryChain;
import cn.xbatis.core.sql.executor.chain.UpdateChain;
import com.ruoyi.common.annotation.DataColumn;
import com.ruoyi.common.annotation.DataPermission;
import com.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.service.UserService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.StreamUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.domain.SysUserPost;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.domain.bo.SysRoleBo;
import com.ruoyi.system.domain.bo.SysUserBo;
import com.ruoyi.system.domain.vo.SysRoleVo;
import com.ruoyi.system.domain.vo.SysUserVo;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 用户 业务层处理
 *
 * @author Lion Li
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SysUserServiceImpl implements ISysUserService, UserService {

    private final SysUserMapper baseMapper;
    private final SysDeptMapper deptMapper;
    private final SysRoleMapper roleMapper;
    private final SysPostMapper postMapper;
    private final SysUserRoleMapper userRoleMapper;
    private final SysUserPostMapper userPostMapper;
    private final ISysRoleService roleService;

    @DataPermission({
        @DataColumn(key = "deptName", value = "d.dept_id"),
        @DataColumn(key = "userName", value = "u.user_id")
    })
    @Override
    public TableDataInfo<SysUserVo> selectPageUserList(SysUserBo user, PageQuery pageQuery) {
        Pager<SysUserVo> paging = QueryChain.of(baseMapper, this.buildQueryWrapper(user))
            .optimizeOptions(i -> i.optimizeJoin(false))
            .select(SysUser::getUserId
                , SysUser::getDeptId
                , SysUser::getNickName
                , SysUser::getUserName
                , SysUser::getEmail
                , SysUser::getAvatar
                , SysUser::getPhonenumber
                , SysUser::getSex
                , SysUser::getStatus
                , SysUser::getDelFlag
                , SysUser::getLoginIp
                , SysUser::getLoginDate
                , SysUser::getCreateBy
                , SysUser::getCreateTime
                , SysUser::getRemark
            )
            .tableAs(SysDept.class, "d")
            .select(SysDept::getDeptName, SysDept::getLeader)
            .from(SysUser.class)
            .tableAs(SysUser.class, "u")
            .returnType(SysUserVo.class)
            .leftJoin(SysUser::getDeptId, SysDept::getDeptId)
            .paging(Pager.of(pageQuery.getPageNum(), pageQuery.getPageSize()));
        System.out.println(paging);
        return TableDataInfo.builds(paging);
    }

    @Override
    public QueryChain<SysUserVo> selectUserVo(Where where) {
        return QueryChain.of(baseMapper, where)
            .select(SysUser::getUserId
                , SysUser::getDeptId
                , SysUser::getUserName
                , SysUser::getNickName
                , SysUser::getUserType
                , SysUser::getEmail
                , SysUser::getAvatar
                , SysUser::getPhonenumber
                , SysUser::getPassword
                , SysUser::getSex
                , SysUser::getStatus
                , SysUser::getDelFlag
                , SysUser::getLoginIp
                , SysUser::getLoginDate
                , SysUser::getCreateBy
                , SysUser::getCreateTime
                , SysUser::getRemark
            )
            .select(SysDept::getDeptId
                , SysDept::getDeptId
                , SysDept::getDeptName
                , SysDept::getOrderNum
                , SysDept::getLeader
            )
            .returnType(SysUserVo.class)
            .select(SysDept::getStatus, c -> c.as("dept_status"))
//            .select(SysRole::getRoleId
//                , SysRole::getRoleName
//                , SysRole::getRoleKey
////                , SysRole::getRoleSort
////                , SysRole::getDataScope
//            )
//            .select(SysRole::getStatus, c -> c.as("role_status"))
            .from(SysUser.class)
            .leftJoin(SysUser::getDeptId, SysDept::getDeptId)
            .leftJoin(SysUser::getUserId, SysUserRole::getUserId)
            .leftJoin(SysUserRole::getRoleId, SysRole::getRoleId);

    }


    /**
     * 根据条件分页查询用户列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @DataPermission({
        @DataColumn(key = "deptName", value = "d.dept_id"),
        @DataColumn(key = "userName", value = "u.user_id")
    })
    @Override
    public List<SysUserVo> selectUserList(SysUserBo user) {
        return QueryChain.of(baseMapper, this.buildQueryWrapper(user))
            .optimizeOptions(i -> i.optimizeJoin(false))
            .select(SysUser::getUserId
                , SysUser::getDeptId
                , SysUser::getNickName
                , SysUser::getUserName
                , SysUser::getEmail
                , SysUser::getAvatar
                , SysUser::getPhonenumber
                , SysUser::getSex
                , SysUser::getStatus
                , SysUser::getDelFlag
                , SysUser::getLoginIp
                , SysUser::getLoginDate
                , SysUser::getCreateBy
                , SysUser::getCreateTime
                , SysUser::getRemark
            )
            .select(SysDept::getDeptName, SysDept::getLeader)
            .tableAs(SysDept.class, "d")
            .returnType(SysUserVo.class)
            .from(SysUser.class)
            .leftJoin(SysUser::getDeptId, SysDept::getDeptId)
            .list();
    }

    private db.sql.api.impl.cmd.struct.Where buildQueryWrapper(SysUserBo user) {
        Map<String, Object> params = user.getParams();
        db.sql.api.impl.cmd.struct.Where betweenWhere = new Where()
            .eq(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId())
            .like(StringUtils.isNotBlank(user.getUserName()), SysUser::getUserName, user.getUserName())
            .eq(StringUtils.isNotBlank(user.getStatus()), SysUser::getStatus, user.getStatus())
            .like(StringUtils.isNotBlank(user.getPhonenumber()), SysUser::getPhonenumber, user.getPhonenumber())
            .between(params.get("beginTime") != null && params.get("endTime") != null,
                SysUser::getCreateTime, params.get("beginTime"), params.get("endTime"));
        if (ObjectUtil.isNotNull(user.getDeptId())) {
            List<SysDept> deptList = QueryChain.of(deptMapper)
                .select(SysDept::getDeptId)
                .and(SysDept::getAncestors, c -> c.mysql().findInSet(user.getDeptId())).list();
            List<Long> ids = StreamUtils.toList(deptList, SysDept::getDeptId);
            ids.add(user.getDeptId());
            betweenWhere.in(SysUser::getDeptId, ids);
        }
        return betweenWhere;
    }

    /**
     * 根据条件分页查询已分配用户角色列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @DataPermission({
        @DataColumn(key = "deptName", value = "d.dept_id"),
        @DataColumn(key = "userName", value = "u.user_id")
    })
    @Override
    public TableDataInfo<SysUserVo> selectAllocatedList(SysUserBo user, PageQuery pageQuery) {
        db.sql.api.impl.cmd.struct.Where where = new Where().eq(SysUser::getDelFlag, UserConstants.USER_NORMAL)
            .eq(ObjectUtil.isNotNull(user.getRoleId()), SysRole::getRoleId, user.getRoleId())
            .like(StringUtils.isNotBlank(user.getUserName()), SysUser::getUserName, user.getUserName())
            .eq(StringUtils.isNotBlank(user.getStatus()), SysUser::getStatus, user.getStatus())
            .like(StringUtils.isNotBlank(user.getPhonenumber()), SysUser::getPhonenumber, user.getPhonenumber());
        Pager<SysUserVo> paging = QueryChain.of(baseMapper, where)
            .select(
                SysUser::getUserId
                , SysUser::getDeptId
                , SysUser::getUserName
                , SysUser::getNickName
                , SysUser::getEmail
                , SysUser::getPhonenumber
                , SysUser::getStatus
                , SysUser::getCreateTime
            )
            .select(SysDept::getDeptName, SysDept::getLeader)
            .from(SysUser.class)
            .tableAs(SysDept.class, "d")
            .leftJoin(SysUser::getDeptId, SysDept::getDeptId)
            .leftJoin(SysUser::getUserId, SysUserRole::getUserId)
            .leftJoin(SysUserRole::getRoleId, SysRole::getRoleId)
            .returnType(SysUserVo.class)
            .optimizeOptions(i -> i.optimizeJoin(false))
            .paging(Pager.of(pageQuery.getPageNum(), pageQuery.getPageSize()));
        return TableDataInfo.builds(paging);
    }

    /**
     * 根据条件分页查询未分配用户角色列表
     *
     * @param user 用户信息
     * @return 用户信息集合信息
     */
    @DataPermission({
        @DataColumn(key = "deptName", value = "d.dept_id"),
        @DataColumn(key = "userName", value = "u.user_id")
    })
    @Override
    public TableDataInfo<SysUserVo> selectUnallocatedList(SysUserBo user, PageQuery pageQuery) {
        QueryChain.of(userRoleMapper)
            .optimizeOptions(i -> i.optimizeJoin(false))
            .select(SysUser::getUserId)
            .from(SysUser.class)
            .tableAs(SysDept.class, "d")
            .innerJoin(SysUser::getUserId, SysUserRole::getUserId)
            .eq(SysUserRole::getRoleId, user.getRoleId())
            .returnType(Long.class)
            .list();


        List<Long> userIds = userRoleMapper.selectUserIdsByRoleId(user.getRoleId());
        db.sql.api.impl.cmd.struct.Where where = new Where()
            .notIn(CollUtil.isNotEmpty(userIds), SysUser::getUserId, userIds)
            .like(StringUtils.isNotBlank(user.getUserName()), SysUser::getUserName, user.getUserName())
            .like(StringUtils.isNotBlank(user.getPhonenumber()), SysUser::getPhonenumber, user.getPhonenumber())
            .ne(SysRole::getRoleId, user.getRoleId()).or().isNull(SysRole::getRoleId);
        Pager<SysUserVo> paging = QueryChain.of(baseMapper, where)
            .select(
                SysUser::getUserId
                , SysUser::getDeptId
                , SysUser::getUserName
                , SysUser::getNickName
                , SysUser::getEmail
                , SysUser::getPhonenumber
                , SysUser::getStatus
                , SysUser::getCreateTime
            )
            .returnType(SysUserVo.class)
            .select(SysDept::getDeptName, SysDept::getLeader)
            .from(SysUser.class)
            .leftJoin(SysUser::getDeptId, SysDept::getDeptId)
            .leftJoin(SysUser::getUserId, SysUserRole::getUserId)
            .leftJoin(SysUserRole::getRoleId, SysRole::getRoleId)
            .paging(Pager.of(pageQuery.getPageNum(), pageQuery.getPageSize()));
        return TableDataInfo.builds(paging);
    }

    /**
     * 通过用户名查询用户
     *
     * @param userName 用户名
     * @return 用户对象信息
     */
    @Override
    public SysUserVo selectUserByUserName(String userName) {
        Where where = new Where();
        where.eq(SysUser::getUserName, userName);
        SysUserVo sysUser = this.selectUserVo(where).get();
        List<SysRoleVo> sysRoleVos = roleService.selectRolesByUserId(sysUser.getUserId());
        sysUser.setRoles(BeanCopyUtils.copyList(sysRoleVos, SysRoleVo.class));
        return sysUser;
    }

    /**
     * 通过手机号查询用户
     *
     * @param phonenumber 手机号
     * @return 用户对象信息
     */
    @Override
    public SysUserVo selectUserByPhonenumber(String phonenumber) {
        Where where = new Where();
        where.eq(SysUser::getPhonenumber, phonenumber);
        SysUserVo sysUser = this.selectUserVo(where).get();
        List<SysRoleVo> sysRoleVos = roleService.selectRolesByUserId(sysUser.getUserId());
        sysUser.setRoles(BeanCopyUtils.copyList(sysRoleVos, SysRoleVo.class));
        return sysUser;
    }

    /**
     * 通过用户ID查询用户
     *
     * @param userId 用户ID
     * @return 用户对象信息
     */
    @Override
    public SysUserVo selectUserById(Long userId) {
        Where where = new Where();
        where.eq(SysUser::getUserId, userId);
        SysUserVo sysUser = this.selectUserVo(where).get();
        List<SysRoleVo> sysRoleVos = roleService.selectRolesByUserId(sysUser.getUserId());
        sysUser.setRoles(BeanCopyUtils.copyList(sysRoleVos, SysRoleVo.class));
        return sysUser;
    }

    /**
     * 查询用户所属角色组
     *
     * @param userName 用户名
     * @return 结果
     */
    @Override
    public String selectUserRoleGroup(String userName) {

        List<SysRole> list = this.selectRoleVo().where(where -> {
            where
                .eq(SysUser::getUserName, userName);
        }).list();
        if (CollUtil.isEmpty(list)) {
            return StringUtils.EMPTY;
        }
        return StreamUtils.join(list, SysRole::getRoleName);
    }

    public QueryChain<SysRole> selectRoleVo() {
        return QueryChain.of(roleMapper)
            .leftJoin(SysRole::getRoleId, SysUserRole::getRoleId)
            .leftJoin(SysUserRole::getUserId, SysUser::getUserId)
            .leftJoin(SysRole::getCreateBy, 1, SysUser::getUserName, 2)
            .leftJoin(SysUser::getDeptId, SysDept::getDeptId);
    }

    /**
     * 查询用户所属岗位组
     *
     * @param userName 用户名
     * @return 结果
     */
    @Override
    public String selectUserPostGroup(String userName) {
        List<SysPost> list = QueryChain.of(postMapper, new Where().eq(SysUser::getUserName, userName))
            .select(SysPost::getPostId, SysPost::getPostName, SysPost::getPostCode)
            .from(SysPost.class)
            .leftJoin(SysPost::getPostId, SysUserPost::getPostId)
            .leftJoin(SysUserPost::getUserId, SysUser::getUserId)
            .list();
        if (CollUtil.isEmpty(list)) {
            return StringUtils.EMPTY;
        }
        return StreamUtils.join(list, SysPost::getPostName);
    }

    /**
     * 校验用户名称是否唯一
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public boolean checkUserNameUnique(SysUserBo user) {
        boolean exist = baseMapper.exists(where -> {
                where.eq(SysUser::getUserName, user.getUserName())
                    .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId());
            }
        );
        return !exist;
    }

    /**
     * 校验手机号码是否唯一
     *
     * @param user 用户信息
     */
    @Override
    public boolean checkPhoneUnique(SysUserBo user) {
        boolean exist = baseMapper.exists(where -> {
                where.eq(SysUser::getPhonenumber, user.getPhonenumber())
                    .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId());
            }
        );
        return !exist;
    }

    /**
     * 校验email是否唯一
     *
     * @param user 用户信息
     */
    @Override
    public boolean checkEmailUnique(SysUserBo user) {
        boolean exist = baseMapper.exists(where -> {
                where.eq(SysUser::getEmail, user.getEmail())
                    .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId());
            }
        );
        return !exist;
    }

    /**
     * 校验用户是否允许操作
     *
     * @param user 用户信息
     */
    @Override
    public void checkUserAllowed(SysUserBo user) {
        if (ObjectUtil.isNotNull(user.getUserId()) && LoginHelper.isAdmin(user.getUserId())) {
            throw new ServiceException("不允许操作超级管理员用户");
        }
    }

    /**
     * 校验用户是否有数据权限
     *
     * @param userId 用户id
     */
    @Override
    public void checkUserDataScope(Long userId) {
        if (!LoginHelper.isAdmin()) {
            SysUserBo user = new SysUserBo();
            user.setUserId(userId);
            List<SysUserVo> users = this.selectUserList(user);
            if (CollUtil.isEmpty(users)) {
                throw new ServiceException("没有权限访问用户数据！");
            }
        }
    }

    /**
     * 新增保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertUser(SysUserBo user) {
        SysUser sysUser = BeanCopyUtils.copy(user, SysUser.class);
        // 新增用户信息
        int rows = baseMapper.save(sysUser);
        // 新增用户岗位关联
        if (sysUser != null) {
            user.setUserId(sysUser.getUserId());
        }
        insertUserPost(user, false);
        // 新增用户与角色管理
        insertUserRoles(user, false);
        return rows;
    }

    /**
     * 注册用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public boolean registerUser(SysUserBo user) {
        user.setCreateBy(user.getUserId());
        SysUser sysUser = BeanCopyUtils.copy(user, SysUser.class);
        user.setUpdateBy(user.getUserId());
        return baseMapper.save(sysUser) > 0;
    }

    /**
     * 修改保存用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateUser(SysUserBo user) {
        Long userId = user.getUserId();
        // 删除用户与角色关联
        userRoleMapper.delete(where -> where.eq(SysUserRole::getUserId, userId));
        // 新增用户与角色管理
        insertUserRole(user, true);
        // 删除用户与岗位关联
        userPostMapper.delete(where -> {
            where.eq(SysUserPost::getUserId, userId);
        });
        // 新增用户与岗位管理
        insertUserPost(user, true);
        SysUser sysUser = BeanCopyUtils.copy(user, SysUser.class);
        return baseMapper.update(sysUser, c -> c.eq(SysUser::getUserId, userId));
    }

    /**
     * 用户授权角色
     *
     * @param userId  用户ID
     * @param roleIds 角色组
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertUserAuth(Long userId, Long[] roleIds) {
        userRoleMapper.delete(where -> where
            .eq(SysUserRole::getUserId, userId));
        insertUserRole(userId, roleIds, true);
    }

    /**
     * 修改用户状态
     *
     * @param bo 用户信息
     * @return 结果
     */
    @Override
    public int updateUserStatus(SysUserBo bo) {
        SysUser user = BeanCopyUtils.copy(bo, SysUser.class);
        return baseMapper.update(user, c -> c.eq(SysUser::getUserId, user.getUserId()));
    }

    /**
     * 修改用户基本信息
     *
     * @param bo 用户信息
     * @return 结果
     */
    @Override
    public int updateUserProfile(SysUserBo bo) {
        SysUser user = BeanCopyUtils.copy(bo, SysUser.class);
        return baseMapper.update(user, c -> c.eq(SysUser::getUserId, user.getUserId()));
    }

    /**
     * 修改用户头像
     *
     * @param userName 用户名
     * @param avatar   头像地址
     * @return 结果
     */
    @Override
    public boolean updateUserAvatar(String userName, String avatar) {
        int execute = UpdateChain.of(baseMapper, new Where().eq(SysUser::getUserName, userName))
            .set(SysUser::getAvatar, avatar).execute();
        return execute > 0;
    }

    /**
     * 重置用户密码
     *
     * @param bo 用户信息
     * @return 结果
     */
    @Override
    public int resetPwd(SysUserBo bo) {
        SysUser user = BeanCopyUtils.copy(bo, SysUser.class);
        return baseMapper.update(user, c -> c.eq(SysUser::getUserId, user.getUserId()));
    }

    /**
     * 重置用户密码
     *
     * @param userName 用户名
     * @param password 密码
     * @return 结果
     */
    @Override
    public int resetUserPwd(String userName, String password) {
        return UpdateChain.of(baseMapper, new Where().eq(SysUser::getUserName, userName))
            .set(SysUser::getPassword, password).execute();
    }

    /**
     * 新增用户角色信息
     *
     * @param user 用户对象
     */
    public void insertUserRoles(SysUserBo user, boolean clear) {
        this.insertUserRole(user.getUserId(), user.getRoleIds(), clear);
    }

    /**
     * 新增用户岗位信息
     *
     * @param user 用户对象
     */
    public void insertUserPost(SysUserBo user, boolean clear) {
        Long[] posts = user.getPostIds();
        if (ArrayUtil.isNotEmpty(posts)) {
            if (clear) {
                // 删除用户与岗位关联
                userPostMapper.delete(new Where().eq(SysUserPost::getUserId, user.getUserId()));
            }
            // 新增用户与岗位管理
            List<SysUserPost> list = StreamUtils.toList(Arrays.asList(posts), postId -> {
                SysUserPost up = new SysUserPost();
                up.setUserId(user.getUserId());
                up.setPostId(postId);
                return up;
            });
            userPostMapper.save(list);
        }
    }

    /**
     * 新增用户角色信息
     *
     * @param user  用户对象
     * @param clear 清除已存在的关联数据
     */
    private void insertUserRole(SysUserBo user, boolean clear) {
        this.insertUserRole(user.getUserId(), user.getRoleIds(), clear);
    }

    /**
     * 新增用户角色信息
     *
     * @param userId  用户ID
     * @param roleIds 角色组
     */
    public void insertUserRole(Long userId, Long[] roleIds, boolean clear) {
        if (ArrayUtil.isNotEmpty(roleIds)) {
            // 判断是否具有此角色的操作权限
            List<SysRoleVo> roles = roleService.selectRoleList(new SysRoleBo());
            if (CollUtil.isEmpty(roles)) {
                throw new ServiceException("没有权限访问角色的数据");
            }
            List<Long> roleList = StreamUtils.toList(roles, SysRoleVo::getRoleId);
            if (!LoginHelper.isAdmin(userId)) {
                roleList.remove(UserConstants.SUPER_ADMIN_ID);
            }
            List<Long> canDoRoleList = StreamUtils.filter(Arrays.asList(roleIds), roleList::contains);
            if (CollUtil.isEmpty(canDoRoleList)) {
                throw new ServiceException("没有权限访问角色的数据");
            }
            if (clear) {
                // 删除用户与角色关联
                userRoleMapper.delete(new Where().eq(SysUserRole::getUserId, userId));
            }
            // 新增用户与角色管理
            List<SysUserRole> list = StreamUtils.toList(canDoRoleList, roleId -> {
                SysUserRole ur = new SysUserRole();
                ur.setUserId(userId);
                ur.setRoleId(roleId);
                return ur;
            });
            userRoleMapper.saveBatch(list);
        }
    }

    /**
     * 通过用户ID删除用户
     *
     * @param userId 用户ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteUserById(Long userId) {
        // 删除用户与角色关联
        userRoleMapper.delete(where -> where.eq(SysUserRole::getUserId, userId));
        // 删除用户与岗位表
        userPostMapper.delete(where -> {
            where.eq(SysUserPost::getUserId, userId);
        });
        return baseMapper.deleteById(userId);
    }

    /**
     * 批量删除用户信息
     *
     * @param userIds 需要删除的用户ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteUserByIds(Long[] userIds) {
        for (Long userId : userIds) {
            checkUserAllowed(new SysUserBo(userId));
            checkUserDataScope(userId);
        }
        List<Long> ids = Arrays.asList(userIds);
        // 删除用户与角色关联
        userRoleMapper.delete(where -> where.in(SysUserRole::getUserId, ids));
        // 删除用户与岗位表
        userPostMapper.delete(where -> {
            where.in(SysUserPost::getUserId, ids);
        });
        return baseMapper.deleteByIds(ids);
    }

    @Cacheable(cacheNames = CacheNames.SYS_USER_NAME, key = "#userId")
    @Override
    public String selectUserNameById(Long userId) {
        SysUser sysUser = QueryChain.of(baseMapper)
            .select(SysUser::getUserName).eq(SysUser::getUserId, userId)
            .get();

        return ObjectUtil.isNull(sysUser) ? null : sysUser.getUserName();
    }

    /**
     * 通过部门id查询当前部门所有用户
     *
     * @param deptId
     * @return
     */
    @Override
    public List<SysUserVo> selectUserListByDept(Long deptId) {

        return QueryChain.of(baseMapper)
            .eq(SysUser::getDeptId, deptId)
            .orderBy(SysUser::getUserId)
            .returnType(SysUserVo.class)
            .list();
    }
}
